package com.spark.sniffer.plugin.plugins.interceptor;

import java.lang.reflect.Method;

import com.spark.sniffer.constant.PassThroughEnum;
import com.spark.sniffer.logging.api.Logger;
import com.spark.sniffer.logging.api.LoggerFactory;
import com.spark.sniffer.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
import com.spark.sniffer.plugin.interceptor.enhance.MethodInterceptResult;
import com.spark.sniffer.tracing.TracingContext;
import com.spark.sniffer.util.ReflectUtil;
import com.spark.sniffer.util.ReflectUtil.WrapperMethod;

/**
 * 此拦截器配合RocketMQListenerInterceptor一起使用，在消费消息前先处理透传数据，设置到上下文中
 * 
 * @author Cobe
 *
 */
public class RocketMQListenerContainerInterceptor implements InstanceMethodsAroundInterceptor {
    private static final Logger log = LoggerFactory.getLogger(RocketMQListenerContainerInterceptor.class);

    @Override
    public void beforeMethod(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        MethodInterceptResult result) throws Throwable {
        Object messageExt = allArguments[0];
        if (messageExt == null) {
            return;
        }

        // 从消息体properties中获取透传数据设置到上下文中
        WrapperMethod getPropertyMethod = ReflectUtil.getMethod(messageExt, "getProperty", String.class);
        for (PassThroughEnum passThrough : PassThroughEnum.values()) {
            String key = passThrough.getValue();
            String value = getPropertyMethod.invoke(key);

            if (value == null || value.trim().equals("")) {
                continue;
            }

            TracingContext.getContext().putPassThrough(key, value);
            log.debug("put passThrough to context: {}={}", key, value);
        }
    }

    @Override
    public Object afterMethod(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Object ret) throws Throwable {
        return ret;
    }

    @Override
    public void handleMethodException(Object instance, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
        Throwable t) {}
}
